﻿using ByteSite.WinClient.Entitys;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;

namespace ByteSite.WinClient.Common
{
    public static class FileHelper
    {

        /// <summary>
        /// 所有磁盘
        /// </summary>
        /// <returns></returns>
        public static List<DriverInfo> Drivers()
        {
            List<DriverInfo> drives = new List<DriverInfo>();
            foreach (DriveInfo drive in DriveInfo.GetDrives())
            {
                drives.Add(new DriverInfo()
                {
                    Name = drive.Name,
                    DriveType = drive.DriveType.ToString(),
                    DriveFormat = drive.DriveFormat,
                    IsReady = drive.IsReady,
                    AvailableFreeSpace = drive.AvailableFreeSpace,
                    TotalFreeSpace = drive.TotalFreeSpace,
                    TotalSize = drive.TotalSize,
                    VolumeLabel = drive.VolumeLabel,

                });
            }
            return drives;
        }

        /// <summary>
        /// 文件是否存在
        /// </summary>
        /// <param name="fileName">完整文件名</param>
        /// <returns>文件是否存在</returns>
        public static bool FileExists(string fileName)
        {
            return System.IO.File.Exists(fileName);
        }

        /// <summary>
        /// 文件复制
        /// </summary>
        /// <param name="sourceFileName">源文件名</param>
        /// <param name="destFileName">目标文件名(不能为路径)</param>
        /// <param name="overWrite">是否覆盖</param>
        public static void FileCopy(string sourceFileName, string destFileName, bool overWrite)
        {
            System.IO.File.Copy(sourceFileName, destFileName, overWrite);
        }

        /// <summary>
        /// 文件复制(自动覆盖)
        /// </summary>
        /// <param name="sourceFileName">源文件名</param>
        /// <param name="destFileName">目标文件名</param>
        public static void FileCopy(string sourceFileName, string destFileName)
        {
            System.IO.File.Copy(sourceFileName, destFileName, true);
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="fileName">文件名</param>
        public static void FileDelete(string fileName)
        {
            System.IO.File.Delete(fileName);
        }

        /// <summary>
        /// 文件移动
        /// </summary>
        /// <param name="sourceFileName">源文件名</param>
        /// <param name="destFileName">目标文件名</param>
        public static void FileMove(string sourceFileName, string destFileName)
        {
            System.IO.File.Move(sourceFileName, destFileName);
        }

        /// <summary>
        /// 创建文件
        /// </summary>
        /// <param name="fileName">文件名</param>
        public static void FileCreat(string fileName)
        {
            FileStream fs = File.Create(fileName);
            fs.Close();
        }
        /// <summary>
        /// 文件读取
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="code">编码(utf-8)</param>
        /// <returns></returns>
        public static string FileRead(string fileName, Encoding code)
        {
            if (FileExists(fileName))
            {
                using (StreamReader objReader = new StreamReader(fileName, code))
                {
                    string strResult = objReader.ReadToEnd();
                    objReader.Close();
                    return strResult;
                }
            }
            else
            {
                return "";
            }
        }

        /// <summary>
        /// 文件读取(utf-8)
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <returns></returns>
        public static string FileRead(string fileName)
        {
            return FileRead(fileName, Encoding.UTF8);
        }

        /// <summary>
        /// 文件保存
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="content">文件内容</param>
        /// <param name="code">编码</param>
        /// <param name="checkFile">安全检查(源文件是否存在)</param>
        public static int FileSave(string fileName, string content, Encoding code, bool checkFile)
        {
            if (checkFile)
            {
                if (!FileExists(fileName))
                {
                    return 0;
                }
            }
            DirectoryExists(fileName.Remove(fileName.LastIndexOf("\\")), true);
            using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                Byte[] info = code.GetBytes(content);// Encoding.UTF8.GetBytes(content);
                fs.Write(info, 0, info.Length);
                fs.Close();
                return 1;
            }
        }

        /// <summary>
        /// 文件保存(utf-8)
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="content">文件内容</param>
        /// <param name="checkFile">安全检查（源文件是否存在）</param>
        public static int FileSave(string fileName, string content, bool checkFile)
        {
            return FileSave(fileName, content, Encoding.UTF8, checkFile);
        }

        /// <summary>
        /// 文件保存(utf-8,检测源文件)
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="content">文件内容</param>
        public static int FileSave(string fileName, string content)
        {
            return FileSave(fileName, content, true);
        }

        /// <summary>
        /// 获取文件属性
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static FileAttribute FileAttributes(string path)
        {
            FileAttribute file = new FileAttribute();
            FileInfo fileinfo = new FileInfo(path);

            file.CreateTime = File.GetCreationTime(path);
            file.Extension = Path.GetExtension(path);
            file.IsReadOnly = fileinfo.IsReadOnly;
            file.Directory = fileinfo.Directory.Name;
            file.Name = Path.GetFileNameWithoutExtension(path);
            file.Path = path;
            file.ReadTime = File.GetLastAccessTime(path);
            file.Size = new FileInfo(path).Length;
            file.UpdateTime = File.GetLastWriteTime(path);

            return file;
        }


        /// <summary>
        /// 创建文件夹
        /// </summary>
        /// <param name="name">路径</param>
        /// <returns></returns>
        public static void DirectoryCreate(string directoryName)
        {
            var securityRules = new DirectorySecurity();
            securityRules.AddAccessRule(new FileSystemAccessRule(System.Environment.UserName, FileSystemRights.FullControl, AccessControlType.Allow));
            securityRules.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow));
            securityRules.AddAccessRule(new FileSystemAccessRule("NETWORK SERVICE", FileSystemRights.FullControl, AccessControlType.Allow));
                
            Directory.CreateDirectory(directoryName);
        }

        /// <summary>
        /// 移动
        /// </summary>
        /// <param name="sourceName"></param>
        /// <param name="destName"></param>
        public static void DirectoryMove(string sourceName, string destName)
        {
            Directory.Move(sourceName, destName);
        }

        /// <summary>
        /// 删除文件夹
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="recursive">是否删除目录下文件</param>
        public static void DirectoryDelete(string fileName)
        {
            Directory.Delete(fileName, true);
        }

        /// <summary>
        /// 判断文件夹是否存在
        /// </summary>
        /// <param name="directoryName">文件夹名</param>
        /// <param name="creatDirectory">如果没有是否创建</param>
        /// <returns></returns>
        public static bool DirectoryExists(string directoryName, bool creatDirectory)
        {
            if (Directory.Exists(directoryName))
                return true;
            else
            {
                if (creatDirectory)
                {
                    Directory.CreateDirectory(directoryName);
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        /// <summary>
        /// 判断文件夹是否存在
        /// </summary>
        /// <param name="directoryName">文件夹名</param>
        /// <returns></returns>
        public static bool DirectoryExists(string directoryName)
        {
            return DirectoryExists(directoryName, false);
        }

        /// <summary>
        /// 获取文件夹目录下所有文件
        /// </summary>
        /// <param name="path">文件夹路径</param>
        /// <returns></returns>
        public static List<FilesInfo> Files(string path)
        {
            List<FilesInfo> files = new List<FilesInfo>();
            DirectoryInfo dir = new DirectoryInfo(path);
            foreach (FileInfo file in dir.GetFiles())
            {
                files.Add(new FilesInfo()
                {
                    Length = file.Length,
                    Name = file.Name,
                    FullName = file.FullName,
                    type = "file",
                    IsReadOnly = file.IsReadOnly,
                    CreationTime = file.CreationTime,
                    CreationTimeUtc = file.CreationTimeUtc,
                    Extension = file.Extension,
                    LastAccessTime = file.LastAccessTime,
                    LastAccessTimeUtc = file.LastAccessTimeUtc,
                    LastWriteTime = file.LastWriteTime,
                    LastWriteTimeUtc = file.LastWriteTimeUtc

                });
            }
            return files;
        }

        /// <summary>
        /// 获取文件夹下所有文件夹
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static List<FilesInfo> Directories(string path)
        {
            List<FilesInfo> dirs = new List<FilesInfo>();
            DirectoryInfo dir = new DirectoryInfo(path);
            foreach (DirectoryInfo directory in dir.GetDirectories())
            {
                dirs.Add(new FilesInfo()
                {
                    Length = 0,
                    Name = directory.Name,
                    FullName = directory.FullName,
                    type = "directory",
                    CreationTime = directory.CreationTime,
                    CreationTimeUtc = directory.CreationTimeUtc,
                    Extension = directory.Extension,
                    LastAccessTime = directory.LastAccessTime,
                    LastAccessTimeUtc = directory.LastAccessTimeUtc,
                    LastWriteTime = directory.LastWriteTime,
                    LastWriteTimeUtc = directory.LastWriteTimeUtc

                });
            }
            return dirs;
        }

        /// <summary>
        /// 文件夹整体复制
        /// </summary>
        /// <param name="sourcePath">X:\XX\</param>
        /// <param name="destPath">Y:\YY\</param>
        public static void DirectoryCopy(string sourcePath, string destPath)
        {
            try
            {
                // 检查目标目录是否以目录分割字符结束如果不是则添加之
                if (destPath[destPath.Length - 1] != Path.DirectorySeparatorChar)
                    destPath += Path.DirectorySeparatorChar;
                // 判断目标目录是否存在如果不存在则新建之
                if (!Directory.Exists(destPath))
                    Directory.CreateDirectory(destPath);
                // 得到源目录的文件列表，该里面是包含文件以及目录路径的一个数组
                //如果你指向copy目标文件下面的文件而不包含目录请使用下面的方法
                //string[] fileList = Directory.GetFiles(srcPath);
                string[] fileList = Directory.GetFileSystemEntries(sourcePath);
                //遍历所有的文件和目录
                foreach (string file in fileList)
                {
                    //先当作目录处理如果存在这个目录就递归Copy该目录下面的文件
                    if (Directory.Exists(file))
                        DirectoryCopy(file, destPath + Path.GetFileName(file));
                    //否则直接Copy文件
                    else
                        File.Copy(file, destPath + Path.GetFileName(file), true);
                }
            }
            catch (Exception ee)
            {
                throw new Exception(ee.ToString());
            }
        }

    }
}

